package com.example.goband.game;

import com.example.goband.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;

import java.util.HashSet;
import java.util.TreeSet;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 22479
 * Date: 2023-06-02
 * Time: 18:44
 */
@Data
public class Room {

    //棋盘大小
    private static final int MAX_ROW = 15;
    private static final int MAX_COL = 15;

    //使用字符串类型来表示,方便生成唯一值
    private String roomId;

    private User user1;
    private User user2;
    private int whiteUser;

    // 棋盘, 数字 0 表示未落子位置. 数字 1 表示玩家 1 的落子. 数字 2 表示玩家 2 的落子
    private int[][] chessBoard = new int[MAX_ROW][MAX_COL];

    ObjectMapper objectMapper = new ObjectMapper();


    public Room() {
        roomId = UUID.randomUUID().toString();

        //创建保存棋谱的文件 根据roomId命名
    }

    //处理一次落子操作的方法
    public GameResponse putChess(String jsonString) throws JsonProcessingException {
        //记录落子位置
        GameRequest request = objectMapper.readValue(jsonString, GameRequest.class);
        GameResponse resp = new GameResponse();

        //判断是否是平局 -- 局时结束
        if(request.getMessage().equals("deuce")) {
            System.out.println("打成平手!");
            resp.setMessage("deuce");
            resp.setRow(-1);
            resp.setCol(-1);
            resp.setWinner(-1);
            resp.setUserId(-1);
            return resp;
        }

        //判断是否是步时结束请求
        if(request.getMessage().equals("stepTime")) {
            //不落子直接跳过让 轮询到下一个玩家
            System.out.println("轮询到下个玩家下棋!");
            resp.setMessage("stepTime");
            resp.setRow(-1);
            resp.setCol(-1);
            resp.setWinner(0);
            resp.setUserId(request.getUserId());
            return resp;
        }

        //落子请求
        //判断是玩家1落子还是玩家2落子
        int player = (request.getUserId() == user1.getUserId()) ? 1: 2;
        int row = request.getRow();
        int col = request.getCol();
        if(chessBoard[row][col] != 0) {
            //此处客户端位置其实已经判定过,但是为了程序健壮性还是判定
            System.out.println("当前位置已经被占用-->" + "行:" + row + "列:" + col);
            resp.setMessage("error");
            return resp;
        }
        chessBoard[row][col] = player;



        //打印棋盘信息，作用： 1.管理员观察局势   2.用户判定胜负
        printBoard(chessBoard);

        //2.进行胜负判定
        int winner = checkWiner(row,col,player);

        //3.给房间中的所有玩家 + 观站玩家 客户端返回响应
        resp.setCol(col);
        resp.setRow(row);
        resp.setUserId(request.getUserId());
        resp.setWinner(winner);
        resp.setMessage("putChess");

        return resp;
    }

    private void printBoard(int[][] chessBoard) {
        //打印棋盘
        System.out.println("=============================[游戏战况 - 房间号: " + roomId  + "]================================");
        for(int r = 0; r < MAX_ROW; r++) {
            for(int c = 0; c < MAX_COL; c++) {
                System.out.print( " " + chessBoard[r][c] + " ");
            }
            System.out.println();
        }

        System.out.println("====================================================================");

    }

    //这个方法判定此次落子是否分出胜负
    //约定玩家1获胜 返回 玩家1的userId
    //玩家2获胜 返回 玩家2的userId
    //如果胜负未分 返回 0
    public int checkWiner(int row,int col,int chess) {
        //情况1 同一行五子连珠
        for(int c = col - 4; c <= col; c++) {
            try {
                if(chessBoard[row][c] == chess
                        && chessBoard[row][c + 1] == chess
                        && chessBoard[row][c + 2] == chess
                        && chessBoard[row][c + 3] == chess
                        && chessBoard[row][c + 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                //出现越界 忽略即可
                continue;
            }
        }

        //情况2 同一列五子连珠
        for(int r = row - 4; r <= row; r++) {
            try {
                if (chessBoard[r][col] == chess
                        && chessBoard[r + 1][col] == chess
                        && chessBoard[r + 2][col] == chess
                        && chessBoard[r + 3][col] == chess
                        && chessBoard[r + 4][col] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                //出现越界 忽略即可
                continue;
            }
        }

        //情况3和4 x 对角线情况

        //情况3 \ 五子连珠
        for(int c = col - 4, r = row - 4; c <= col && r <= row; c++,r++) {
            try {
                if (chessBoard[r][c] == chess
                        && chessBoard[r + 1][c + 1] == chess
                        && chessBoard[r + 2][c + 2] == chess
                        && chessBoard[r + 3][c + 3] == chess
                        && chessBoard[r + 4][c + 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                //出现越界 忽略即可
                continue;
            }
        }

        //情况4 / 五子连珠
        for(int c = col + 4, r = row - 4; c <= col && r <= row; c++,r++) {
            try {
                if (chessBoard[row][c] == chess
                        && chessBoard[r + 1][c - 1] == chess
                        && chessBoard[r + 2][c - 2] == chess
                        && chessBoard[r + 3][c - 3] == chess
                        && chessBoard[r + 4][c - 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                //出现越界 忽略即可
                continue;
            }
        }

//        //和棋代码 考虑...
//        //判断棋盘是否满
//        int count = 0;
//        for(int r = 0; r < MAX_ROW; r++) {
//            for(int c = 0; c < MAX_COL; c++) {
//               if(count != 0) {
//                   count++;
//               }
//            }
//        }
//        if(count == 15 * 15) {
//            //和棋
//            return 3;
//        }

        return 0;
    }

}
